



// keyof : 索引类型
// type B = keyof A
// let value:B = 'password'


type B = {
  username?:string;
  password?:number;
  age:number
  sex?:number
};

// in 遍历 
type MyReadonly<T> ={
  readonly[P in keyof T] : T[P]
}

let readonlyA : MyReadonly<A> ={
  username:'123',
  password:456
} 

// readonlyA.password = 1244

// 可选项
type MyPartial<T> = {
  [P in keyof T] ?: T[P]
}

let partialA:MyPartial<A> = {
  // 都变成可选项
}

// 必选项
type MyRequired<T> = {
  [P in keyof T] -?: T[P]
} 

let requiredA:MyRequired<A> = {
  username: "",
  password: 0,
  age:0
}
// 挑出一些类型 
// A 挑出 username password
type MyPick<T , K extends keyof T> = {
  // 
  [P in K] : T[P]
}
let pickA :MyPick<A,'username'|'password'> = {
  // password:'123'
  username:'123',
  password : 12344,
}




// 排除类型 
type A = {
  username?:string;
  password?:number;
  age?:number
};

type C  = {
  username?:string;
  password?:number;
  age?:number;
  number:number
}
// 



// 将 除了 username 和 password 的项 都排除
// let excludeA :Excludes<A,C>  = {
//   number:123
// }
type Excludes<K,T> = K extends T ? never : K
type MyOmit1<T, K extends keyof T> = MyPick<T , Excludes<keyof T,K>> 
let abc1 :MyOmit1<A,'password'> = {
  username:'123',
  age:123
  // password:1233
  // age:123
} 


interface Person123 {
  name: string;
  age: number;
}

type K1 = keyof Person123; // "name" | "age"
type K2 = keyof Person123[]; // "length" | "toString" | "pop" | "push" | "concat" | "join"
type K3 = keyof { [x: string]: Person123 };  